import { createHash } from 'crypto';
import fs, { existsSync } from 'fs';
import path from 'path';
import { app } from 'electron';
import { mkdirSync } from 'node:fs';

class FileUtils {
  public static formatBytes(bytes: number, decimals: number = 2): string {
    if (bytes === 0) return '0 Bytes';
    const k = 1024; // 1 KB = 1024 Bytes
    const dm = decimals < 0 ? 0 : decimals; // Ensure decimal places are not less than 0
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];

    const i = Math.floor(Math.log(bytes) / Math.log(k)); // Calculate unit index
    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; // Return formatted string
  }

  public static calculateFileChecksum(filePath: string) {
    const fileBuffer = fs.readFileSync(filePath);
    const hash = createHash('sha256');
    hash.update(fileBuffer);
    return hash.digest('hex');
  }

  public static mkdir(path: string) {
    if (!fs.existsSync(path)) {
      fs.mkdirSync(path, { recursive: true, mode: 0o777 });
    }
  }

  /**
   * Windows    %APPDATA%/<YourAppName>                         C:\Users\you\AppData\Roaming\MyApp
   * macOS      ~/Library/Application Support/<YourAppName>     /Users/you/Library/Application Support/MyApp
   * Linux      ~/.config/<YourAppName>                         /home/you/.config/MyApp
   */
  public static logDir() {
    const dir = path.join(app.getPath('userData'), 'logs');
    if (!existsSync(dir)) {
      mkdirSync(dir, { recursive: true });
    }
    return dir;
  }

  public static getDailyLogFile(prefix = '') {
    const date = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
    const fileName = prefix ? `${prefix}-${date}.log` : `${date}.log`;
    return path.join(this.logDir(), fileName);
  }

  public static cleanOldLogs(logDir: string, keepDays = 7) {
    const now = Date.now();
    const files = fs.readdirSync(logDir);

    files.forEach((file) => {
      const filePath = path.join(logDir, file);
      if (!file.endsWith('.log')) return;

      const stat = fs.statSync(filePath);
      if (now - stat.mtimeMs > keepDays * 86400 * 1000) {
        fs.unlinkSync(filePath);
      }
    });
  }
}

export default FileUtils;
